library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity SF_rcv_interface is
	port(
		reset, clk: in std_logic;
		--inputs from Xuan
		rcv_drdreq, rcv_lrdreq, packet_finished: in std_logic;

		--inputs from RCV ports
		rcv0_data, 	rcv1_data, 	rcv2_data, 	rcv3_data: in std_logic_vector(7 downto 0);
		rcv0_length,rcv1_length,rcv2_length,rcv3_length: in std_logic_vector(11 downto 0);
		rcv0_qempty,rcv1_qempty,rcv2_qempty,rcv3_qempty: in std_logic;
		
		--outputs to Xuan
		rcv_data: out std_logic_vector(7 downto 0);
		rcv_length: out std_logic_vector(11 downto 0);
		
		port_number: out std_logic_vector(1 downto 0);
		connection_ready: out std_logic;
		
		--outputs to RCV ports
		rcv0_drdreq, 	rcv1_drdreq, 	rcv2_drdreq, 	rcv3_drdreq: out std_logic;
		rcv0_lrdreq, 	rcv1_lrdreq, 	rcv2_lrdreq, 	rcv3_lrdreq: out std_logic
	);
end SF_rcv_interface;

architecture arch of SF_rcv_interface is
	type STATE is (RST, C0, R0, C1, R1, C2, R2, C3, R3);
	signal state_cur : STATE;
	signal state_next : STATE;
	signal rcv0_pktrdy, rcv1_pktrdy, rcv2_pktrdy, rcv3_pktrdy: std_logic;
	signal data_rdreq, length_rdreq: std_logic_vector(3 downto 0);
	
	begin
	--convert length empty to packet ready signals for convenience
	rcv0_pktrdy <= NOT rcv0_qempty;
	rcv1_pktrdy <= NOT rcv1_qempty;
	rcv2_pktrdy <= NOT rcv2_qempty;
	rcv3_pktrdy <= NOT rcv3_qempty;
	
	
	rcv0_drdreq<=data_rdreq(0);
	rcv1_drdreq<=data_rdreq(1);
	rcv2_drdreq<=data_rdreq(2);
	rcv3_drdreq<=data_rdreq(3);
	rcv0_lrdreq<=length_rdreq(0);
	rcv1_lrdreq<=length_rdreq(1);
	rcv2_lrdreq<=length_rdreq(2);
	rcv3_lrdreq<=length_rdreq(3);
				
	
		--register
	process(clk, reset)
	begin
		if reset='1' then
			state_cur <= RST;
		elsif (clk'event and clk='1') then
			state_cur <= state_next;
		end if;
	end process;
	--next state logic
	state_next <=
		C0 when (state_cur=RST) else
		C0 when (state_cur=R3 and packet_finished='1') else
		C0 when (state_cur=C3 and rcv3_pktrdy='0') else
		
		R0 when (state_cur=C0 and rcv0_pktrdy='1') else
		R0 when (state_cur=R0 and packet_finished='0') else
		
		C1 when (state_cur=C0 and rcv0_pktrdy='0') else
		C1 when (state_cur=R0 and packet_finished='1') else
		
		R1 when (state_cur=C1 and rcv1_pktrdy='1') else
		R1 when (state_cur=R1 and packet_finished='0') else
		
		C2 when (state_cur=C1 and rcv1_pktrdy='0') else
		C2 when (state_cur=R1 and packet_finished='1') else
		
		R2 when (state_cur=C2 and rcv2_pktrdy='1') else
		R2 when (state_cur=R2 and packet_finished='0') else
		
		C3 when (state_cur=C2 and rcv2_pktrdy='0') else
		C3 when (state_cur=R2 and packet_finished='1') else
				
		R3 when (state_cur=C3 and rcv3_pktrdy='1') else
		R3 when (state_cur=R3 and packet_finished='0') else
		
		RST; --handle exceptions
	--output logic

	port_number <=
		"00" when (reset='1') else
		"00" when (state_cur=C0 OR state_cur=R0) else
		"01" when (state_cur=C1 OR state_cur=R1) else
		"10" when (state_cur=C2 OR state_cur=R2) else
		"11" when (state_cur=C3 OR state_cur=R3) else
		"00";

	-- pass through busses
 	rcv_data <= 
		rcv0_data when (state_cur=R0) else
		rcv1_data when (state_cur=R1) else
		rcv2_data when (state_cur=R2) else
		rcv3_data when (state_cur=R3) else
      "00000000";

 	rcv_length <= 
		rcv0_length when (state_cur=R0) else
		rcv1_length when (state_cur=R1) else
		rcv2_length when (state_cur=R2) else
		rcv3_length when (state_cur=R3) else
      "000000000000";

	connection_ready<=
		'1' when (state_cur=R0 OR state_cur=R1 OR state_cur=R2 OR state_cur=R3) else
		'0';

 -- data read requests
	data_rdreq(0) <=
		rcv_drdreq when (state_cur=R0) else
		'0';
	data_rdreq(1) <=
		rcv_drdreq when (state_cur=R1) else
		'0';
	data_rdreq(2) <=
		rcv_drdreq when (state_cur=R2) else
		'0';
	data_rdreq(3) <=
		rcv_drdreq when (state_cur=R3) else
		'0';

 -- length read requests
	length_rdreq(0) <=
		rcv_lrdreq when (state_cur=R0) else
		'0';
	length_rdreq(1) <=
		rcv_lrdreq when (state_cur=R1) else
		'0';
	length_rdreq(2) <=
		rcv_lrdreq when (state_cur=R2) else
		'0';
	length_rdreq(3) <=
		rcv_lrdreq when (state_cur=R3) else
		'0';
	

--
--	process(clk,reset)
--	begin
--		if(reset ='1') then port_number<="00";
--		elsif (clk'event and clk='1') then
--			if(state_cur=C0) then 
--				connection_ready <='0';
--				port_number<="00";
--				--set outputs to rcv ports to 0
--				data_rdreq <= "0000";
--				length_rdreq <= "0000";
--				
--			elsif(state_cur=R0) then
--				connection_ready <='1';
--				--pass through outputs to rcv ports 
--				data_rdreq(0) <= rcv_drdreq;
--				length_rdreq(0) <= rcv_lrdreq;				
--				--pass through rcv signals to fabric
--				rcv_data <= rcv0_data;
--				rcv_length <= rcv0_length;
--				
--			elsif(state_cur=C1) then 
--				connection_ready <='0';
--				port_number<="01";
--				--set outputs to rcv ports to 0
--				data_rdreq <= "0000";
--				length_rdreq <= "0000";				
--			
--			elsif(state_cur=R1) then
--				connection_ready <='1';
--				--pass through outputs to rcv ports 
--				data_rdreq(1) <= rcv_drdreq;
--				length_rdreq(1) <= rcv_lrdreq;				
--				--pass through rcv signals to fabric
--				rcv_data <= rcv1_data;
--				rcv_length <= rcv1_length;
--					
--			elsif(state_cur=C2) then 
--				connection_ready <='0';
--				port_number<="10";
--				--set outputs to rcv ports to 0
--				data_rdreq <= "0000";
--				length_rdreq <= "0000";				
--			
--			elsif(state_cur=R2) then
--				connection_ready <='1';
--				--pass through outputs to rcv ports 
--				data_rdreq(2) <= rcv_drdreq;
--				length_rdreq(2) <= rcv_lrdreq;				
--				--pass through rcv signals to fabric
--				rcv_data <= rcv2_data;
--				rcv_length <= rcv2_length;
--					
--			elsif(state_cur=C3) then 
--				connection_ready <='0';
--				port_number<="11";
--				--set outputs to rcv ports to 0
--				data_rdreq <= "0000";
--				length_rdreq <= "0000";				
--			
--			elsif(state_cur=R3) then
--				connection_ready <='1';
--				--pass through outputs to rcv ports 
--				data_rdreq(3) <= rcv_drdreq;
--				length_rdreq(3) <= rcv_lrdreq;				
--				--pass through rcv signals to fabric
--				rcv_data <= rcv3_data;
--				rcv_length <= rcv3_length;
--							
--			end if;
--		end if;
--	end process;
	
end arch;